package com.fsnbigdata.config;

import com.fsnbigdata.domain.dto.OrgProdDTO;
import com.fsnbigdata.service.EnterpriseProcessor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.task.SimpleAsyncTaskExecutor;

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

//    @Autowired
//    public DataSource dataSource;

    @Autowired
    public JobRepository jobRepository;

    // tag::readerwriterprocessor[]
    @Bean
    public FlatFileItemReader<OrgProdDTO> reader() {
        FlatFileItemReader<OrgProdDTO> reader = new FlatFileItemReader<OrgProdDTO>();
        reader.setResource(new ClassPathResource("org_prod.csv"));
        reader.setLineMapper(new DefaultLineMapper<OrgProdDTO>() {{
            setLineTokenizer(new DelimitedLineTokenizer() {{
                setNames(new String[] { "orgName", "legalPerson", "address", "contactName", "contactNumber", "productName", "barcode", "specification", "brand", "expiration", "ingredients", "targetGroup", "nutrition"});
            }});
            setFieldSetMapper(new BeanWrapperFieldSetMapper<OrgProdDTO>() {{
                setTargetType(OrgProdDTO.class);
            }});
        }});
        return reader;
    }

    @Bean
    public EnterpriseProcessor processor() {
        return new EnterpriseProcessor();
    }

//    @Bean
//    public JdbcBatchItemWriter<OrgProdDTO> writer() {
//        JdbcBatchItemWriter<OrgProdDTO> writer = new JdbcBatchItemWriter<OrgProdDTO>();
////        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<OrgProdDTO>());
////        writer.setSql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)");
////        writer.setDataSource(dataSource);
//        return writer;
//    }
    // end::readerwriterprocessor[]

    // tag::jobstep[]
    @Bean
    public Job importUserJob() {
        return jobBuilderFactory.get("importUserJob")
                .incrementer(new RunIdIncrementer())
                //.listener(listener)
                .flow(step1())
                .end()
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<OrgProdDTO, OrgProdDTO> chunk(100)
                .reader(reader())
                .processor(processor())
                //.writer(writer())
                .build();
    }
    // end::jobstep[]

    @Bean
    public JobLauncher jobLauncher() throws Exception {
        SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
        jobLauncher.setJobRepository(jobRepository);
        jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
        jobLauncher.afterPropertiesSet();
        return jobLauncher;
    }
}
